﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;

namespace EHR.Ctrls.QueryDesign
{
    public partial class FilterItem : FilterItemBase
    {
        private FilterInfo _filterInfo;
        public event EventHandler Deleting;
        private IList<ColInfo> Columns { get; set; }
        public object FilterValue
        {
            get { return (object)GetValue(FilterValueProperty); }
            set { SetValue(FilterValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FilterValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FilterValueProperty =
            DependencyProperty.Register("FilterValue", typeof(object), typeof(FilterItem), new PropertyMetadata(null));



        public int DataType
        {
            get { return (int)GetValue(DataTypeProperty); }
            set { SetValue(DataTypeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataType.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataTypeProperty =
            DependencyProperty.Register("DataType", typeof(int), typeof(FilterItem), new PropertyMetadata(0));


        public string Operator
        {
            get { return (string)GetValue(OperatorProperty); }
            set { SetValue(OperatorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Operator.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OperatorProperty =
            DependencyProperty.Register("Operator", typeof(string), typeof(FilterItem), new PropertyMetadata(""));

        public string Column
        {
            get { return (string)GetValue(ColumnProperty); }
            set { SetValue(ColumnProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsEditState.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ColumnProperty =
            DependencyProperty.Register("Column", typeof(string), typeof(FilterItem), new PropertyMetadata(""));

        public FilterItem()
        {
            InitializeComponent();
            
            LayoutRoot.DataContext = this;

            cmbOp.ItemsSource = FilterOpHelper.AllOps;
            cmbOp.SelectedIndex = 0;
        }

        private ColInfo SelectedCol
        {
            get
            {
                if (cmbCol == null)
                {
                    return null;
                }
                if (cmbCol.SelectedIndex == -1)
                {
                    return null;
                }
                return Columns[cmbCol.SelectedIndex];
            }
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            Save();
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (Deleting != null)
            {
                Deleting(this, new EventArgs());
            }
        }

        private void FilterItemBase_Loaded(object sender, RoutedEventArgs e)
        {
        }

        public void Save()
        {
            if (!Validate())
            {
                return;
            }

            IsEditState = false;

            RaiseSaved();
        }

        public override bool Validate()
        {
            ColInfo col = SelectedCol;
            if (col == null)
            {
                MessageBox.Show("请选择列！");
                return false;
            }

            if (string.IsNullOrWhiteSpace(txtVal.Text))
            {
                txtVal.Text = txtVal.Text.Trim();
            }
            FilterOp op = (FilterOp)cmbOp.SelectedIndex;
            if (col.AllowNull && (op == FilterOp.等于 || op == FilterOp.不等于))
            {
                if (string.IsNullOrEmpty(txtVal.Text))
                {
                    return true;
                }
            }

            switch (col.FieldType)
            {                
                case FieldType.Bool:
                    txtVal.Text = txtVal.Text.Trim();
                    switch (txtVal.Text)
                    {
                        case "0":
                        case "1":
                            return true;
                        default:
                            MessageBox.Show("过滤条件：格式不正确, 请输入 0 或者 1 ! (说明：0为未选中；1为选中)");
                        return false;
                    }
                case FieldType.Int:
                    txtVal.Text = txtVal.Text.Trim();
                    int iVal;
                    if (int.TryParse(txtVal.Text, out iVal))
                    {
                        txtVal.Text = iVal.ToString();
                        return true;
                    }
                    else
                    {
                        MessageBox.Show("过滤条件：格式不正确, 请输入整数！");
                        return false;
                    }
                case FieldType.Float:
                    txtVal.Text = txtVal.Text.Trim();
                    double dVal;
                    if (double.TryParse(txtVal.Text, out dVal))
                    {
                        txtVal.Text = dVal.ToString();
                        return true;
                    }
                    else
                    {
                        MessageBox.Show("过滤条件：格式不正确， 请输入数值！");
                        return false;
                    }
                case FieldType.DateTime:
                    DateTime tVal;
                    if (DateTime.TryParse(txtVal.Text, out tVal))
                    {
                        txtVal.Text = txtVal.Text.Trim();
                        return true;
                    }
                    else
                    {
                        MessageBox.Show("过滤条件：格式不正确，请输入时间! (比如：2000-1-1 或者 2000-1-1 8:20 或者 2000-1-1 8:20:45)");
                        return false;
                    }
                default:
                    return true;
            }
        }

        public void SetFilterInfo(FilterInfo fi)
        {
            _filterInfo = fi;

            cmbCol.SelectedIndex = IndexOfFieldName(fi.FieldName);
            cmbOp.SelectedIndex = (int)fi.Op;
            txtVal.Text = fi.Value.ToString();

            Operator = OpMiniString(FilterOpHelper.AllOps[(int)fi.Op]);
        }

        public FilterInfo GetFilterInfo()
        {
            FilterInfo i = new FilterInfo();
            i.FieldName = SelectedCol.FieldName;
            i.Op = (FilterOp)cmbOp.SelectedIndex;
            i.Value = txtVal.Text;
            return i;
        }

        private int IndexOfFieldName(string fieldName)
        {
            for(int i = 0; i < Columns.Count; i++)
            {
                var col = Columns[i];
                if (col.FieldName == fieldName)
                {
                    return i;
                }
            }

            return -1;
        }

        public void SetColumns(IList<ColInfo> cols)
        {
            Columns = cols;
            cmbCol.ItemsSource = cols;
            cmbCol.SelectedValuePath = "DisplayName";
            cmbCol.DisplayMemberPath = "DisplayName";
            cmbCol.SelectedIndex = 0;
        }

        private void cmbOp_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbOp == null)
            {
                return;
            }

            if (cmbOp.SelectedIndex == -1)
            {
                return;
            }

            string val = cmbOp.SelectedValue.ToString();
            Operator = OpMiniString(val);
        }

        private string OpMiniString(string op)
        {
            return op.Split(' ')[0];
        }

        private void cmbCol_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ColInfo col = SelectedCol;

            if (col == null)
            {
                return;
            }
            if (col.FieldType != FieldType.String)
            {
                if (col.FieldType == FieldType.Bool)
                {
                    if (cmbOp.SelectedIndex > 1)
                    {
                        cmbOp.SelectedIndex = 0;
                    }
                }
                if (cmbOp.SelectedIndex >= FilterOpHelper.AllOps.Count - 2)
                {
                    cmbOp.SelectedIndex = 0;
                }
            }

            int selectedIndex = cmbOp.SelectedIndex;
            cmbOp.ItemsSource = FilterOps(col);
            cmbOp.SelectedIndex = selectedIndex;
        }

        private IList<string> FilterOps(ColInfo col)
        {
            if (col.FieldType == FieldType.String)
            {
                return FilterOpHelper.AllOps;
            }

            IList<string> list = new List<string>();

            if (col.FieldType == FieldType.Bool)
            {
                list.Add(FilterOpHelper.AllOps[0]);
                list.Add(FilterOpHelper.AllOps[1]);
                return list;
            }

            foreach (string i in FilterOpHelper.AllOps)
            {
                if (i.IndexOf("包含") == -1 && i.IndexOf("始于") == -1)
                {
                    list.Add(i);
                }
            }

            return list;
        }

        private bool FilterOps(object obj)
        {
            if (SelectedCol == null)
            {
                return true;
            }
            if (SelectedCol.FieldType == FieldType.String)
            {
                return true;
            }

            string op = obj as string;
            if (op.IndexOf("包含") != -1 || op.IndexOf("始于") != -1)
            {
                return false;
            }

            return true;
        }

        private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            RaiseClicked();
        }

        private void txtVal_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                Save();
            }
        }

        private void overColComboBoxBorder_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!cmbCol.IsDropDownOpen)
            {
                cmbCol.IsDropDownOpen = true;
            }
        }

        private void overOpComboBoxBorder_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!cmbOp.IsDropDownOpen)
            {
                cmbOp.IsDropDownOpen = true;
            }
        }

    }
}
